Skip to content

feat(ev-deployer): part 3a - add live chain deployment via CREATE2#200

Open
randygrok wants to merge 19 commits intoev-deployer-part3-permit2from
ev-deployer-part3a
Open

feat(ev-deployer): part 3a - add live chain deployment via CREATE2#200
randygrok wants to merge 19 commits intoev-deployer-part3-permit2from
ev-deployer-part3a

Conversation

@randygrok
Copy link
Copy Markdown
Contributor

@randygrok randygrok commented Mar 30, 2026

Summary

Adds a deploy subcommand to ev-deployer for deploying AdminProxy and Permit2 contracts to a live chain via CREATE2 using the deterministic deployer factory.

Previously, ev-deployer could only generate genesis alloc JSON for pre-genesis deployment. This PR adds the ability to deploy the same contracts to an already-running chain, with deterministic addresses, state persistence, and idempotent resume.

Key changes

  • Optional addresses in configaddress is now Option<Address> in contract configs. Required for genesis mode (validated at runtime), ignored in deploy mode where CREATE2 determines the address.
  • CREATE2 module — Computes deterministic addresses using Nick's factory (0x4e59b44847b379578588920ca78fbf26c0b4956c).
  • Deploy state file — JSON state file tracks a random salt, the original config intent, and per-contract status (pendingdeployedverified). Immutability checks prevent config drift between runs.
  • ChainDeployer trait — Abstracts on-chain operations (get_code, deploy_create2). LiveDeployer implements it with alloy provider + signer.
  • Deploy pipeline — Orchestrates: connect → verify factory exists → deploy each contract → verify bytecodes on-chain. Fully idempotent (skips already-deployed contracts).

Usage

# Deploy to a live chain
ev-deployer deploy \
  --config deploy.toml \
  --rpc-url http://localhost:8545 \
  --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \
  --state deploy-state.json \
  --addresses-out addresses.json

# RPC URL and private key can also be set via env vars
export EV_DEPLOYER_RPC_URL=http://localhost:8545
export EV_DEPLOYER_PRIVATE_KEY=0xac0974...
ev-deployer deploy --config deploy.toml --state deploy-state.json

The state file is created on first run and reused on subsequent runs for resumability. If a deploy is interrupted, re-running the same command picks up where it left off.

@randygrok randygrok requested a review from a team as a code owner March 30, 2026 15:39
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 30, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fe50a179-76f9-42e9-9b50-6dd242af934a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ev-deployer-part3a

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@claude
Copy link
Copy Markdown

claude bot commented Mar 30, 2026

Claude finished @randygrok's task —— View job


Code Review for ev-deployer Part 3a - Live Chain Deployment

Reviewing the implementation of live chain deployment via CREATE2 for the ev-deployer tool.

Todo List

  • Read repository guidelines and context
  • Analyze core architecture and design changes
  • Review configuration changes and validation
  • Examine CREATE2 implementation and security
  • Check deploy pipeline and state management
  • Assess error handling and resilience
  • Evaluate test coverage
  • Provide comprehensive feedback

Review Summary

This is a solid implementation of live chain deployment functionality that extends ev-deployer beyond genesis alloc generation. The architecture is well-designed with clear separation of concerns and proper abstractions.

✅ Positive Aspects

  1. Excellent Architecture Design

    • Clean separation between genesis and deploy modes via trait abstraction (ChainDeployer)
    • Proper modularization in the deploy/ module
    • Well-designed state management with immutability guarantees
  2. Robust State Management

    • Atomic file operations for state persistence (bin/ev-deployer/src/deploy/state.rs:89-96)
    • Immutability validation prevents config drift between runs (bin/ev-deployer/src/deploy/state.rs:98-119)
    • Random salt generation for CREATE2 determinism
  3. Strong Idempotency

    • Graceful handling of already-deployed contracts (bin/ev-deployer/src/deploy/pipeline.rs:145-149)
    • Bytecode verification for correctness (bin/ev-deployer/src/deploy/pipeline.rs:151-173)
    • Resume capability from interrupted deployments
  4. Good Security Practices

    • Environment variable support for sensitive data (bin/ev-deployer/src/main.rs:78-82)
    • Proper validation of zero addresses and duplicates (bin/ev-deployer/src/config.rs:92-124)
    • Chain ID verification to prevent wrong-chain deployments (bin/ev-deployer/src/deploy/pipeline.rs:38-43)

🔧 Areas for Improvement

1. Missing AdminProxy Support

The pipeline only handles Permit2 deployment but the config supports AdminProxy. Need to add AdminProxy deployment logic in pipeline.rs.

// bin/ev-deployer/src/deploy/pipeline.rs:226-238
fn get_contract_status(state: &DeployState, name: &str) -> Option<ContractStatus> {
    if name == "permit2" {
        state.contracts.permit2.as_ref().map(|c| c.status)
    } else {
        None  // AdminProxy support missing
    }
}

2. Error Handling Improvements

  • Gas estimation: No gas estimation before deployment, could lead to failed transactions
  • Network errors: Basic retry logic would improve reliability for network operations
  • Transaction replacement: No handling of stuck transactions due to gas price issues

3. Security Considerations

  • Private key handling: Keys are stored in memory as strings. Consider using SecretString or similar for better security
  • Factory existence check: Only checks for non-empty code, doesn't verify the actual factory bytecode (bin/ev-deployer/src/deploy/pipeline.rs:46-51)

4. Configuration Design Concern

Making address optional creates confusion:

// bin/ev-deployer/src/config.rs:61-62
pub struct AdminProxyConfig {
    /// Address to deploy at (required for genesis, ignored for deploy).
    pub address: Option<Address>,

This could be clearer with separate config types for genesis vs deploy modes.

5. Test Coverage Gaps

  • No integration tests for the full deploy pipeline
  • Mock testing is good but lacks real network scenarios
  • Missing tests for error conditions like network failures
  • No tests for AdminProxy deployment (because it's not implemented)

6. Documentation & UX

  • CLI help: Could be more descriptive about the two deployment modes
  • State file format: No versioning strategy documented for future schema changes
  • Recovery scenarios: Limited guidance on handling failed deployments

🏗️ Architecture Comments

The trait-based design is excellent and allows for easy testing and future extensibility. The separation between CREATE2 computation, state management, and deployment orchestration is well thought out.

🧪 Test Quality

The existing tests are well-structured with good coverage of core logic:

  • Config validation tests are comprehensive (bin/ev-deployer/src/config.rs:151-367)
  • CREATE2 tests verify address computation (bin/ev-deployer/src/deploy/create2.rs:32-75)
  • State management tests cover immutability (bin/ev-deployer/src/deploy/state.rs:131-227)
  • Pipeline tests use proper mocking (bin/ev-deployer/src/deploy/pipeline.rs:324-400)

📊 Performance Considerations

  • State file I/O is well-optimized with atomic writes
  • Bytecode verification could be cached but probably not necessary for typical usage
  • Network calls are appropriately async

🚀 Recommendations

  1. High Priority: Implement AdminProxy deployment support
  2. Medium Priority: Add gas estimation and retry logic for robustness
  3. Medium Priority: Improve private key security handling
  4. Low Priority: Consider splitting config types for genesis vs deploy modes
  5. Low Priority: Add integration tests with test networks

This is a high-quality implementation that demonstrates good Rust practices and thoughtful system design. The main gap is the incomplete contract support, but the foundation is solid for future extensions.


AdminProxy has an empty constructor and sets owner via genesis storage
slot 0, making it incompatible with live CREATE2 deployment where the
owner would remain address(0). Restrict AdminProxy to genesis-only mode.
Write to a .tmp file first, then rename into place. Prevents
state file corruption if the process crashes mid-write.
@randygrok randygrok changed the title feat(ev-deployer): add live chain deployment via CREATE2 feat(ev-deployer): Part 3a add live chain deployment via CREATE2 Mar 31, 2026
@randygrok randygrok changed the title feat(ev-deployer): Part 3a add live chain deployment via CREATE2 feat(ev-deployer): part 3a - add live chain deployment via CREATE2 Mar 31, 2026
Inject Nick's CREATE2 factory (0x4e59b44847b379578588920ca78fbf26c0b4956c)
into genesis state so ev-deployer deploy works on post-merge chains
where the canonical keyless transaction cannot land. Genesis-only —
the deploy pipeline already validates its existence on-chain.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant